//
//  PacketTunnelProvider.swift
//  WATFFTVTunnel
//
//  Created by one on 2024/1/5.
//

import NetworkExtension
import NEKit
import PacketProcessor_iOS
class PacketTunnelProvider: NEPacketTunnelProvider {

    private var watf_shadServers: WATFFTVServers?
    private var watf_shadHanderl: ((Error?) -> Void)?
    override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {

        guard let watf_ftvConfig = options?["watf_options"] as? [String : Any] else {
            completionHandler(NEVPNError(.configurationDisabled))
            return
        }
        self.watf_shadHanderl = completionHandler
        self.watf_shadServers = WATFFTVServers(watf_ftvConfig)
        watf_shadServers?.start(withConnectivityChecks: false) { [weak self] error in
            if error == .noError {
                self?.watf_setNetSeings()
            } else {
                self?.watf_shadHanderl?(NEVPNError(.connectionFailed))
            }
        }
    }
    
    private func watf_setNetSeings() {
        let ipList = [String]()
        
        var ipV4ExcludedRoutes = [NEIPv4Route]()
        var ipV6ExcludedRoutes = [NEIPv6Route]()
        
        ipList.forEach { ip in
            if ip.contains(":") {
                ipV6ExcludedRoutes.append(NEIPv6Route(destinationAddress: ip, networkPrefixLength: 128))
            } else {
                ipV4ExcludedRoutes.append(NEIPv4Route(destinationAddress: ip, subnetMask: "255.255.255.255"))
            }
        }
        
        let watf_ipV4Sting = NEIPv4Settings(addresses: ["192.168.20.2"], subnetMasks: ["255.255.255.0"])
        watf_ipV4Sting.includedRoutes = [.default()]
        watf_ipV4Sting.excludedRoutes = ipV4ExcludedRoutes
        
        let watf_ipV6Sting = NEIPv6Settings(addresses: ["fd66:f83a:c650::1"], networkPrefixLengths: [120])
        watf_ipV6Sting.includedRoutes = [.default()]
        watf_ipV6Sting.excludedRoutes = ipV6ExcludedRoutes
        
        let watf_dnsSegs = NEDNSSettings(servers: ["8.8.8.8", "8.8.4.4", "1.1.1.1", "1.0.0.1"])
        
        let watf_routsetting = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "192.168.20.1")
        watf_routsetting.ipv4Settings = watf_ipV4Sting
        watf_routsetting.ipv6Settings = watf_ipV6Sting
        watf_routsetting.dnsSettings = watf_dnsSegs
        
        setTunnelNetworkSettings(watf_routsetting) { error in
            if let error = error {
                self.watf_shadHanderl?(error)
                return
            }
            self.watf_setSSTunnel()
        }
    }
    
    private func watf_setSSTunnel() {
        
        if let error = TunnelInterface.setup(with: self.packetFlow) {
            self.watf_shadHanderl?(error)
            return
        }
        
        let port: Int32 = self.watf_shadServers!.localSSPort
        TunnelInterface.setIsUdpForwardingEnabled(true)
        TunnelInterface.startTun2Socks(port)
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            TunnelInterface.processPackets()
        }
        
        self.watf_shadHanderl?(nil)
    }
    
    override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
        TunnelInterface.stop()
        watf_shadServers?.stop({ _ in
            
        })
        completionHandler()
    }
    
    override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
        if let msg = String(data: messageData, encoding: String.Encoding.utf8) {
            if msg == "CANCEL_VPN" {
                watf_shadServers?.stop({ _ in
                })
                return
            }
        }
        if let handler = completionHandler {
            handler(messageData)
        }
    }
    
    override func sleep(completionHandler: @escaping () -> Void) {
        completionHandler()
    }
    //
    override func wake() {
        // Add code here to wake up.
    }
    
}

